#!/usr/bin/env python3
"""
Alpha026-050因子使用示例
=======================

展示如何使用新实现的Alpha026-050因子进行量化分析。
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import sys
import os

# 添加项目路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from alpha101.core import Alpha101Factory, AlphaFactor
from alpha101.config import get_factor_config, list_factors_by_category

def generate_sample_data(n_stocks=100, n_days=252):
    """
    生成示例股票数据
    
    Parameters:
    -----------
    n_stocks : int
        股票数量
    n_days : int
        交易日数量
        
    Returns:
    --------
    dict
        股票数据字典
    """
    np.random.seed(42)
    
    # 生成股票代码
    stock_codes = [f"STOCK_{i:03d}" for i in range(n_stocks)]
    
    # 生成日期序列
    dates = pd.date_range('2023-01-01', periods=n_days, freq='D')
    
    # 生成基础价格数据
    base_price = 50.0
    price_data = np.zeros((n_stocks, n_days))
    
    for i in range(n_stocks):
        # 生成随机游走价格序列
        returns = np.random.normal(0.0005, 0.02, n_days)  # 日收益率
        prices = [base_price * (1 + np.random.normal(0, 0.1))]  # 初始价格
        
        for j in range(1, n_days):
            prices.append(prices[-1] * (1 + returns[j]))
        
        price_data[i, :] = prices
    
    # 生成OHLC数据
    close = price_data
    high = close * (1 + np.abs(np.random.normal(0, 0.01, (n_stocks, n_days))))
    low = close * (1 - np.abs(np.random.normal(0, 0.01, (n_stocks, n_days))))
    open_price = np.roll(close, 1, axis=1)
    open_price[:, 0] = close[:, 0]
    open_price = open_price * (1 + np.random.normal(0, 0.005, (n_stocks, n_days)))
    
    # 生成成交量数据
    volume = np.random.lognormal(10, 1, (n_stocks, n_days))
    
    # 生成VWAP数据
    vwap = (high + low + close) / 3.0
    
    # 计算收益率
    returns = np.zeros_like(close)
    returns[:, 1:] = (close[:, 1:] - close[:, :-1]) / close[:, :-1]
    
    # 计算20日平均成交量
    adv20 = np.zeros_like(volume)
    for i in range(20, n_days):
        adv20[:, i] = np.mean(volume[:, i-19:i+1], axis=1)
    adv20[:, :20] = volume[:, :20]
    
    return {
        'close': close,
        'open': open_price,
        'high': high,
        'low': low,
        'volume': volume,
        'vwap': vwap,
        'returns': returns,
        'adv20': adv20,
        'stock_codes': stock_codes,
        'dates': dates
    }

def demonstrate_single_factor():
    """演示单个因子的使用"""
    print("=" * 60)
    print("单个因子使用示例")
    print("=" * 60)
    
    # 创建因子工厂
    factory = Alpha101Factory(use_numba=False)
    
    # 生成示例数据
    data = generate_sample_data(n_stocks=50, n_days=100)
    
    # 选择一个因子进行演示
    factor_id = "alpha026"
    
    # 获取因子信息
    config = get_factor_config(factor_id)
    print(f"因子ID: {factor_id}")
    print(f"公式: {config['formula']}")
    print(f"描述: {config['description']}")
    print(f"类别: {config['category']}")
    print(f"依赖项: {config['dependencies']}")
    print(f"时间窗口: {config['window']}")
    
    # 计算因子值
    print(f"\n计算因子值...")
    factor_values = factory.compute_factor(factor_id, data)
    
    print(f"因子值形状: {factor_values.shape}")
    print(f"有效值数量: {np.sum(~np.isnan(factor_values))}")
    print(f"有效值比例: {np.sum(~np.isnan(factor_values)) / factor_values.size:.2%}")
    
    # 统计信息
    valid_values = factor_values[~np.isnan(factor_values)]
    if len(valid_values) > 0:
        print(f"\n统计信息:")
        print(f"均值: {np.mean(valid_values):.6f}")
        print(f"标准差: {np.std(valid_values):.6f}")
        print(f"最小值: {np.min(valid_values):.6f}")
        print(f"最大值: {np.max(valid_values):.6f}")
        print(f"分位数 (25%, 50%, 75%): {np.percentile(valid_values, [25, 50, 75])}")

def demonstrate_batch_computation():
    """演示批量计算多个因子"""
    print("\n" + "=" * 60)
    print("批量因子计算示例")
    print("=" * 60)
    
    # 创建因子工厂
    factory = Alpha101Factory(use_numba=False)
    
    # 生成示例数据
    data = generate_sample_data(n_stocks=30, n_days=100)
    
    # 选择几个因子进行批量计算
    factor_ids = ["alpha026", "alpha027", "alpha028", "alpha029", "alpha030"]
    
    print(f"批量计算因子: {factor_ids}")
    
    # 批量计算
    results = factory.batch_compute(factor_ids, data)
    
    print(f"\n计算结果:")
    print("-" * 40)
    for factor_id, factor_values in results.items():
        if factor_values is not None:
            valid_count = np.sum(~np.isnan(factor_values))
            valid_ratio = valid_count / factor_values.size
            print(f"{factor_id}: 有效值 {valid_count}/{factor_values.size} ({valid_ratio:.1%})")
        else:
            print(f"{factor_id}: 计算失败")

def demonstrate_factor_analysis():
    """演示因子分析"""
    print("\n" + "=" * 60)
    print("因子分析示例")
    print("=" * 60)
    
    # 创建因子工厂
    factory = Alpha101Factory(use_numba=False)
    
    # 生成示例数据
    data = generate_sample_data(n_stocks=50, n_days=150)
    
    # 选择几个不同类别的因子
    factor_ids = ["alpha026", "alpha033", "alpha041", "alpha044", "alpha050"]
    
    # 计算因子值
    factor_results = {}
    for factor_id in factor_ids:
        factor_values = factory.compute_factor(factor_id, data)
        factor_results[factor_id] = factor_values
    
    # 分析因子相关性
    print("因子相关性分析:")
    print("-" * 40)
    
    # 计算最后一天的因子值相关性
    last_day_factors = {}
    for factor_id, values in factor_results.items():
        last_day_values = values[:, -1]
        valid_mask = ~np.isnan(last_day_values)
        if np.sum(valid_mask) > 10:  # 至少10个有效值
            last_day_factors[factor_id] = last_day_values[valid_mask]
    
    # 计算相关系数矩阵
    if len(last_day_factors) > 1:
        factor_names = list(last_day_factors.keys())
        n_factors = len(factor_names)
        corr_matrix = np.zeros((n_factors, n_factors))
        
        for i, factor1 in enumerate(factor_names):
            for j, factor2 in enumerate(factor_names):
                if i == j:
                    corr_matrix[i, j] = 1.0
                else:
                    # 找到两个因子的共同有效值
                    values1 = last_day_factors[factor1]
                    values2 = last_day_factors[factor2]
                    min_len = min(len(values1), len(values2))
                    if min_len > 5:
                        corr = np.corrcoef(values1[:min_len], values2[:min_len])[0, 1]
                        corr_matrix[i, j] = corr if not np.isnan(corr) else 0.0
        
        # 显示相关性矩阵
        print(f"{'':>10}", end="")
        for name in factor_names:
            print(f"{name:>10}", end="")
        print()
        
        for i, name in enumerate(factor_names):
            print(f"{name:>10}", end="")
            for j in range(n_factors):
                print(f"{corr_matrix[i, j]:>10.3f}", end="")
            print()

def demonstrate_factor_categories():
    """演示按类别查看因子"""
    print("\n" + "=" * 60)
    print("因子分类展示")
    print("=" * 60)
    
    # 获取Alpha026-050的因子列表
    alpha_026_050 = [f"alpha{i:03d}" for i in range(26, 51)]
    
    # 按类别分组
    categories = {}
    for factor_id in alpha_026_050:
        try:
            config = get_factor_config(factor_id)
            category = config['category']
            if category not in categories:
                categories[category] = []
            categories[category].append(factor_id)
        except:
            continue
    
    # 显示各类别的因子
    for category, factors in categories.items():
        print(f"\n{category.upper()} 类因子 ({len(factors)}个):")
        print("-" * 30)
        for factor_id in factors:
            config = get_factor_config(factor_id)
            print(f"  {factor_id}: {config['description']}")

def main():
    """主函数"""
    print("Alpha026-050因子使用示例")
    print("=" * 60)
    
    try:
        # 演示单个因子使用
        demonstrate_single_factor()
        
        # 演示批量计算
        demonstrate_batch_computation()
        
        # 演示因子分析
        demonstrate_factor_analysis()
        
        # 演示因子分类
        demonstrate_factor_categories()
        
        print("\n" + "=" * 60)
        print("示例运行完成！")
        print("=" * 60)
        
    except Exception as e:
        print(f"运行出错: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()